// opencv async detector demo
// Author: lihaoweicv@hotmail.com
// MIT License


#ifndef CV_ASYNC_DEMO_MACRO_H
#define CV_ASYNC_DEMO_MACRO_H

#include <cstdio>
#include <cstdlib>

//#define  LOG_DETAIL

//visibility
#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#ifdef __GNUC__
#define PUBLIC __attribute__((dllexport))
#else
#define PUBLIC __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define PUBLIC __attribute__((dllimport))
#else
#define PUBLIC __declspec(dllimport)
#endif
#endif
#define LOCAL_FUNC
#else
#if __GNUC__ >= 4
#define PUBLIC __attribute__((visibility("default")))
#define LOCAL_FUNC __attribute__((visibility("hidden")))
#else
#define PUBLIC
#define LOCAL_FUNC
#endif
#endif

//Simple Log
// Log
#ifdef __ANDROID__
#include <android/log.h>
#define LOGDT(fmt, tag, ...)                                                                                           \
    __android_log_print(ANDROID_LOG_DEBUG, tag,("" fmt), ##__VA_ARGS__)
#define LOGIT(fmt, tag, ...)                                                                                           \
    __android_log_print(ANDROID_LOG_INFO, tag, ("" fmt), ##__VA_ARGS__)
#define LOGET(fmt, tag, ...)                                                                                           \
    __android_log_print(ANDROID_LOG_ERROR, tag, ("%s [File %s][Line %d] " fmt), __PRETTY_FUNCTION__, __FILE__,         \
                        __LINE__, ##__VA_ARGS__);                                                                      \
    fprintf(stderr, ("E/%s: %s [File %s][Line %d] " fmt), tag, __PRETTY_FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)

#else

#ifdef LOG_DETAIL
#define LOGDT(fmt, tag, ...)                                                                                           \
    fprintf(stdout, ("D/%s: %s [file %s][line %d] " fmt), tag, __PRETTY_FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOGIT(fmt, tag, ...)                                                                                           \
    fprintf(stdout, ("I/%s: %s [file %s][line %d] " fmt), tag, __PRETTY_FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOGET(fmt, tag, ...)                                                                                           \
    fprintf(stderr, ("E/%s: %s [file %s][line %d] " fmt), tag, __PRETTY_FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)

#else

#define LOGDT(fmt, tag, ...)                                                                                           \
    fprintf(stdout, ("D/%s:  " fmt), tag,  ##__VA_ARGS__)
#define LOGIT(fmt, tag, ...)                                                                                           \
    fprintf(stdout, ("I/%s:  " fmt), tag,  ##__VA_ARGS__)
#define LOGET(fmt, tag, ...)                                                                                           \
    fprintf(stderr, ("E/%s:  " fmt), tag,  ##__VA_ARGS__)

#endif
#endif  //__ANDROID__

//#if _WIN32
#define NO_GLOG
//#endif

#ifdef  NO_GLOG
#define LOGD(fmt, ...) LOGDT(fmt, "cvf", ##__VA_ARGS__)
#define LOGI(fmt, ...) LOGIT(fmt, "cvf", ##__VA_ARGS__)
#define LOGE(fmt, ...) LOGET(fmt, "cvf", ##__VA_ARGS__)
#else
#include <glog/logging.h>
#define LOGD(fmt, ...)  { std::string buffer;buffer.resize(1024);\
                             sprintf(&buffer[0], ("D/%s:  " fmt), "cvf",  ##__VA_ARGS__); \
                             LOG(WARNING) << buffer;\
                             }
#define LOGI(fmt, ...)  { std::string buffer;buffer.resize(1024);\
                             sprintf(&buffer[0], ("I/%s:  " fmt), "cvf",  ##__VA_ARGS__); \
                             LOG(INFO) << buffer;\
                             }
#define LOGE(fmt, ...)  { std::string buffer;buffer.resize(1024);\
                             sprintf(&buffer[0], ("E/%s:  " fmt), "cvf",  ##__VA_ARGS__); \
                             LOG(ERROR) << buffer;\
                             }
#endif

// Assert
#include <cassert>
#ifndef  ASSERT
#include <cassert>
#define ASSERT(x) \
    {\
        int res = (x);\
        if (!res) {\
            LOGE("Error: assert failed\n");\
            assert(res);\
        }\
    }
#endif // ! ASSERT


#ifdef NO_LOG
#undef LOGDT
#undef LOGD
#define LOGDT(fmt, tag, ...)
#define LOGD(fmt, ...)
#undef ASSERT
#define ASSERT(x)
#endif  // NO_LOG


// Math
#ifndef UP_DIV
#define UP_DIV(x, y) (((int)(x) + (int)(y) - (1)) / (int)(y))
#endif
#ifndef ROUND_UP
#define ROUND_UP(x, y) (((int)(x) + (int)(y) - (1)) / (int)(y) * (int)(y))
#endif
#ifndef ALIGN_UP4
#define ALIGN_UP4(x) ROUND_UP((x), 4)
#endif
#ifndef ALIGN_UP8
#define ALIGN_UP8(x) ROUND_UP((x), 8)
#endif
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif
#ifndef ABS
#define ABS(x) ((x) > (0) ? (x) : (-(x)))
#endif

#ifndef  CLAMP
#define  CLAMP(v , lo, hi)   (v < lo) ? lo : (hi < v) ? hi : v;
#endif


#ifdef _WIN32
#include <windows.h>
PUBLIC int gettimeofday(struct timeval *tp, void *tzp);
#else
#include <ctime>
#endif


#define PRINT_DEBUG_MSG 0
#if PRINT_DEBUG_MSG
#define ADD_TRACK  {\
     LOGI("run here!");\
    }
#else
#define ADD_TRACK  ;
#endif


#endif //CV_ASYNC_DEMO_MACRO_H
